﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using ALDIOrganizer.Properties;

namespace ALDIOrganizer
{
    public partial class MainForm
    {
        void REQUESTS_BindControls()
        {
            cbPositionsEmployeesRequest.DataSource = GetJobTitlesDataSource;
            cbPositionsEmployeesRequest.DisplayMember = "Key";
            cbPositionsEmployeesRequest.ValueMember = "Value";
            cbPositionsEmployeesRequest.SelectedIndex = 0;
            dgridRequests.DataError += // assigning an empty event handler effectively disables this event.
                delegate { };
            dgridRequestsPending.DataError += // assigning an empty event handler effectively disables this event.
                delegate { };
            
        }
        
        List<Int64> GetAllIDsFromlbEmployeesRequests
        {
            get
            {
                return (from object t in lbEmployeesRequests.Items
                        select (Int64)(t as DataRowView)[0]).ToList();
            }
        }

        private bool IsUsersOwnPendingRequestSelected
        {
            get
            {
                if (GetSelectedPendingRequest == null)
                {
                    return false;
                }
                return GetSelectedPendingRequest.empID == Program.Logged.ID;
            }
        }
        void dgridRequests_Populate()
        {
            var ids = new List<Int64>();
            if (rbShowEverybodysRequests.Checked)
            {
                ids = GetAllIDsFromlbEmployeesRequests;
            }
            else
            {
                if (rbShowOnlySomeonesRequests.Checked &&
                    lbEmployeesRequests.SelectedIndex >= 0)
                {
                    ids.Add((Int64) lbEmployeesRequests.SelectedValue);
                }
            }
            var pending = cbIncludePendingRequests.Checked ? null : (bool?)false;
            var passed = cbIncludePassedRequests.Checked ? null : (bool?)false;


            var dataview = SQLiteAccess.GetRequestsDataView(
                ids.ToArray(),
                pending,
                passed);
            var source = (from DataRowView row in dataview
                          select new Request(row.Row)).ToList();
            dgridRequests.DataSource = source;
        }

        void dgridRequestsPending_Populate()
        {
            var ids = GetAllIDsFromlbEmployeesRequests;
            var pending = (bool?)true;
            var passed = (bool?)false;
            var dataview = SQLiteAccess.GetRequestsDataView(
                ids.ToArray(),
                pending,
                passed);
            var source = (from DataRowView row in dataview select new Request(row.Row)).ToList();
            dgridRequestsPending.DataSource = source;
        }



        void lbEmployeesRequest_Populate()
        {
            SQLiteAccess.CalculateAllColumns();

            #region setting filter
            var filter1 = String.Empty;
            if (cbRequestsJustCurrentEmployees.Checked)
            {
                filter1 += Resources.MAINFORM_REQUESTS_ShowJustCurrentEmployees_ROWFILTERVALUE;                
            }

            var filter2 = cbPositionsEmployeesRequest.SelectedValue ?? String.Empty;


            var filterJoined = filter1 +
                ((filter1 == String.Empty || filter2.ToString() == String.Empty)
                ? String.Empty : " AND ")
                + filter2;

            SQLiteAccess.SetFilterForStaffOnRequestsTab(filterJoined);
            #endregion


            var backup = lbEmployeesRequests.SelectedValue;
            lbEmployeesRequests.DataSource = null;
            lbEmployeesRequests.DisplayMember = "displayColumn";
            lbEmployeesRequests.ValueMember = "id";
            lbEmployeesRequests.DataSource = SQLiteAccess.EmployeesForRequestsTab;
            lbEmployeesRequests.GoTo(backup);
            lbEmployeesRequests.Refresh();
            
        }

        void dgridRequests_SelectionChanged(object sender, EventArgs e)
        {
            var anythingSelected = GetSelectedRequest != null;
            btnAddRequest.Enabled = Program.Logged.CanEditRequests;
            btnEditRequest.Enabled = Program.Logged.CanEditRequests &&
                anythingSelected;
            btnDeleteRequest.Enabled = Program.Logged.CanEditRequests &&
                anythingSelected;
        }

        void dgridRequestsPending_SelectionChanged(object sender, EventArgs e)
        {
            var anythingSelected = GetSelectedPendingRequest != null;
            btnAddPendingRequest.Enabled = Program.Logged.CanEditRequests ||
                !Program.Logged.NotAnEmployee;
            btnAcceptPendingRequest.Enabled = anythingSelected &&
                Program.Logged.CanEditRequests;
            btnRejectPendingRequest.Enabled = anythingSelected &&
                (Program.Logged.CanEditRequests ||
                IsUsersOwnPendingRequestSelected); // anyone can reject their own request (changed their mind)
            btnEditPendingRequest.Enabled = anythingSelected &&  // something has to be selected, AND
                ((Program.Logged.CanEditRequests) || // either user entitled to edit requests, OR
                (Program.Logged.CanViewRequests && IsUsersOwnPendingRequestSelected)); /* only entitled to view requests,
                                                                                        * but the highlighted request happens to be
                                                                                        * his (or her) own, thus allowing them
                                                                                        * to modify it. */
            
        }

        private void DeleteRequest(
            Request pRequest,
            string pConfirmationMsgBoxText,
            string pConfirmationMsgBoxCaption)
        {
            if (pRequest == null)
            {
                return;
            }
            var _sure = MessageBox.Show(
                pConfirmationMsgBoxText,
                pConfirmationMsgBoxCaption,
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question);
            if (_sure == DialogResult.No)
            {
                return;
            }
            Hourglass(true);
            SQLiteAccess.DeleteRequest(pRequest.ID);
            Sounds.Play(Sounds.Validated);
            Hourglass(false);
        }

        void btnRejectPendingRequest_Click(object sender, EventArgs e)
        {
            DeleteRequest(
                GetSelectedPendingRequest,
                Resources.MESSAGEBOX_QUESTION_RejectRequest_MESSAGE,
                Resources.MESSAGEBOX_QUESTION_RejectRequest_CAPTION);
        }

        void btnAcceptPendingRequest_Click(object sender, EventArgs e)
        {
            SwitchPendingRequest(
                GetSelectedPendingRequest,
                false);
        }

        private void SwitchPendingRequest(Request pRequest, bool new_pending_value)
        {
            Hourglass(true);
            var row = pRequest.Row;
            row[7] = new_pending_value;
            SQLiteAccess.UpdateRequest(
                (Int64)row[0],
                row);
            Sounds.Play(Sounds.Validated);
            Hourglass(false);
        }
        
        void btnDeleteRequest_Click(object sender, EventArgs e)
        {
            DeleteRequest(
                GetSelectedRequest,
                Resources.MESSAGEBOX_QUESTION_DeleteRequest_MESSAGE,
                Resources.MESSAGEBOX_QUESTION_DeleteRequest_CAPTION);
        }

        /// <summary>
        /// Returns the currently selected request from dgridRequests datagridview (top panel)
        /// </summary>
        /// <remarks>
        /// If no request is selected (because the control is empty, for example) null is returned.
        /// </remarks>
        Request GetSelectedRequest
        {
            get
            {
                if (dgridRequests.SelectedRows.Count == 0)
                {
                    return null;
                }
                return dgridRequests.SelectedRows[0].DataBoundItem as Request;
            }
        }

        /// <summary>
        /// Returns the currently selected pending request from dgridRequestsPending datagridview (bottom panel)
        /// </summary>
        /// <remarks>
        /// If no request is selected (because the control is empty, for example) null is returned.
        /// </remarks>
        Request GetSelectedPendingRequest
        {
            get
            {
                if (dgridRequestsPending.SelectedRows.Count == 0)
                {
                    return null;
                }
                return dgridRequestsPending.SelectedRows[0].DataBoundItem as Request;
            }
        }
                

        void cbRequestsJustCurrentEmployees_CheckedChanged(object sender, EventArgs e)
        {
            lbEmployeesRequest_Populate();
            dgridRequests_Populate();
        }

        void lbEmployeesRequests_SelectedValueChanged(object sender, EventArgs e)
        {
            if (lbEmployeesRequests.Tag != null &&            
                lbEmployeesRequests.Tag.GetType() == typeof(bool) &&
                (bool)lbEmployeesRequests.Tag)
            {
                return;
            }
            if (lbEmployeesRequests.SelectedValue == null)
            {
                return;
            }
            var _id = (Int64)lbEmployeesRequests.SelectedValue;
            var _name = SQLiteAccess.GetEmployeeFirstName(_id);
            rbShowOnlySomeonesRequests.Text = rbShowOnlySomeonesRequests.Tag.ToString().Replace("#",
                _name);

            dgridRequests_Populate();
        }

        void cbPositionEmployeesRequest(object sender, EventArgs e)
        {            
            lbEmployeesRequest_Populate();            
        }

        private void AddRequest(bool? pPending)
        {
            var _PossibleIDs = GetAllIDsFromlbEmployeesRequests.ToArray();
            Int64 id;

            /* Managers will be allowed to edit requests (anybody'pShift),
             * so they get to choose for whom they actually want to AddAnotherRowString the request for. */
            if (Program.Logged.CanEditRequests)
            {
                Program.ChooseEmployee = new ForWhom(
                    Resources.FORM_FORWHOM_Title_Requests,
                    _PossibleIDs);
                if (Program.ChooseEmployee.ShowDialog() == DialogResult.OK)
                {
                    id = Program.ChooseEmployee.GetID;
                }
                else
                {
                    return;
                }
            }
            /* If currently logged user is not allowed to edit requests,
             * it effectively means he is only entitled to AddAnotherRowString requests for himself
             * (or herself). Therefore, User.ID property must be examined to see which
             * employee he (she) actually is. */
            else
            {
                /* This will happen if the value is not set. Logged in user
                 * is not "mapped" to any person from the Employees DataTable.
                 * In such case, user will see a pMessage box with a brief explanation
                 * and that'pShift it. We exit the method. */
                if (Program.Logged.NotAnEmployee)
                {
                    MessageBox.Show(
                        Resources.MESSAGEBOX_ERROR_AddingRequestSomebodyElseAttempted_MESSAGE,
                        Resources.MESSAGEBOX_ERROR_AddingRequestSomebodyElseAttempted_CAPTION,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                    return;
                }                
                id = Program.Logged.ID;                
            }
            /* At this point we have successfuly determined WHO is the request for
             * (one way or another).
             * Now we need to establish details of the request itself. */
            Program.requestForm = new RequestDetails(null,
                InputAction.Create,
                pPending);
            if (Program.requestForm.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            Hourglass(true);
            SQLiteAccess.AddNewRequest(
                id,
                Program.requestForm.DataBoundRequest.Row);
            Sounds.Play(Sounds.Validated);
            Hourglass(false);
        }
        
        private void btnAddRequest_Click(object sender, EventArgs e)
        {
            AddRequest((bool?)null);            
        }

        void btnAddPendingRequest_Click(object sender, EventArgs e)
        {
            AddRequest((bool?)true);
        }

        private void EditRequest(Request pSelectedRequest)
        {
            if (pSelectedRequest == null)
            {
                return;
            }
            Program.requestForm = new RequestDetails(
                pSelectedRequest.Row,
                InputAction.Update,
                (bool?)null);
            if (Program.requestForm.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            Hourglass(true);
            SQLiteAccess.UpdateRequest(
                pSelectedRequest.ID,
                Program.requestForm.DataBoundRequest.Row);
            Sounds.Play(Sounds.Validated);
            Hourglass(false);
        }

        void btnEditRequest_Click(object sender, EventArgs e)
        {
            EditRequest(GetSelectedRequest);
        }

        void btnEditPendingRequest_Click(object sender, EventArgs e)
        {
            EditRequest(GetSelectedPendingRequest);
        }

        internal void EditRequest(Int64 pRequestID)
        {
            EditRequest(new Request(SQLiteAccess.GetRequest(pRequestID)));            
        }
    }
}
